package com.hzlj.position.dbsync.liaoning.rest;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fz.common.base.core.JsonUtils;
import com.fz.common.base.exception.PubException;
import com.hzlj.position.dbsync.liaoning.common.dto.zhizunWd.request.*;
import com.hzlj.position.dbsync.liaoning.common.dto.zhizunWd.response.ZhizunWdDeviceLocationQueryResultDTO;
import com.hzlj.position.dbsync.liaoning.common.enums.AudioMsgType;
import com.hzlj.position.dbsync.liaoning.config.ZhizunConfig;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Slf4j
@Service
public class ZhizunRest {
    //4.1.1查询设备信息（设备位置、电量、UID可调用此接口获取）
    private final static String DEVICE_LOCATION_URI = "/deviceLocationQuery.action";
    //4.2.5设置定位频率
    private final static String LOCATION_FREQUENCY_URI = "/locationFrequency.action";
    //4.2.12 设置低电量报警
    private final static String LOWBAT_URI = "/lowbat.action";
    //4.3.1 发送查找设备指令
    private final static String FIND_DEVICE_URI = "/findDevice.action";
    //4.6.4微聊信息推送
    private final static String SEND_MSG_URI = "/sendMsgLog.action";
    //4.3.3发送远程关机指令(需要设备支持此功能)
    private final static String SHUT_DOWN_URI = "/shutdown.action";

    @Resource
    private ZhizunConfig zhizunConfig;

    /**
     * 4.1.1查询设备信息（设备位置、电量、UID可调用此接口获取）
     */
    public ZhizunWdDeviceLocationQueryResultDTO getDeviceLocation(String imei) {
        ZhizunDeviceLocationQueryDTO params = new ZhizunDeviceLocationQueryDTO();
        params.setDeviceList(imei);
        List<ZhizunWdDeviceLocationQueryResultDTO> locations
                = executeList(DEVICE_LOCATION_URI, params, "获取位置", ZhizunWdDeviceLocationQueryResultDTO.class);
        return locations.get(0);
    }

    /**
     * 4.1.1查询设备信息（设备位置、电量、UID可调用此接口获取）（多个）
     */
    public List<ZhizunWdDeviceLocationQueryResultDTO> getDeviceLocations(List<String> imeis) {
        ZhizunDeviceLocationQueryDTO params = new ZhizunDeviceLocationQueryDTO();
        params.setDeviceList(String.join(",", imeis));
        return executeList(DEVICE_LOCATION_URI, params, "获取位置", ZhizunWdDeviceLocationQueryResultDTO.class);
    }

    /**
     * 4.1.1查询设备信息（设备位置、电量、UID可调用此接口获取）（多个）
     */
    public void updateLocationFrequency(String imei, String frequency) {
        ZhizunLocationFrequencyUpdateDTO update = new ZhizunLocationFrequencyUpdateDTO();
        update.setFQCY(frequency);
        update.setMID(imei);
        this.execute(LOCATION_FREQUENCY_URI, update, "修改定位频率");
    }

    /**
     * 4.2.12 设置低电量报警
     * lowbat:true开启
     */
    public void updateLowbat(String imei, boolean lowbat) {
        ZhizunLowbatUpdateDTO update = new ZhizunLowbatUpdateDTO();
        update.setUID(getUid(imei));
        update.setLowBat(lowbat ? 1 : 0);
        this.execute(LOWBAT_URI, update, "设置低电量报警");
    }

    /**
     * 4.3.1 发送查找设备指令
     */
    public void findDevice(String imei) {
        ZhizunFindDeviceDTO update = new ZhizunFindDeviceDTO();
        update.setMID(imei);
        this.execute(FIND_DEVICE_URI, update, "查找设备");
    }

    /**
     * 4.3.3发送远程关机指令(需要设备支持此功能)
     */
    public void shutdown(String imei) {
        ZhizunShutDownDTO update = new ZhizunShutDownDTO();
        update.setUID(getUid(imei));
        this.execute(SHUT_DOWN_URI, update, "远程关机");
    }

    /**
     * 4.6.4微聊信息推送
     */
    public void sendAudioMsg(String imei, AudioMsgType msgType) {
        ZhizunSendMsgDTO sendMsg = new ZhizunSendMsgDTO();
        sendMsg.setMType(1);
        sendMsg.setMID(imei);
        switch (msgType) {
            case CROSS:
                sendMsg.setFileID(zhizunConfig.getMsg().getCrossFileId());
                sendMsg.setContent(zhizunConfig.getMsg().getCrossMsg());
                break;
            case DEMOUNT:
                sendMsg.setFileID(zhizunConfig.getMsg().getDemountFileId());
                sendMsg.setContent(zhizunConfig.getMsg().getDemountMsg());
                break;
            default:
                throw new PubException("没有配置语音文件");
        }
        sendMsg.setAmrLen(sendMsg.getContent().length());
        this.execute(SEND_MSG_URI, sendMsg, "微聊信息推送(语音)");
    }


    /**
     * 4.6.4微聊信息推送
     */
    public void sendTextMsg(String imei, String msg) {
        ZhizunSendMsgDTO sendMsg = new ZhizunSendMsgDTO();
        sendMsg.setMType(0);
        sendMsg.setMID(imei);
        sendMsg.setContent(msg);
        sendMsg.setFileID("1");
        sendMsg.setAmrLen(sendMsg.getContent().length());
        this.execute(SEND_MSG_URI, sendMsg, "微聊信息推送(文本)");
    }


    @SuppressWarnings("unchecked")
    private <T> List<T> executeList(String uri,
                                    ZhizunCommonRequestDTO params,
                                    String buss,
                                    Class<T> clazz) {
        log.info("【智尊】获取数据({})：params={}", buss, JsonUtils.obj2json(params));
        params.setAppId(zhizunConfig.getAppId());
        params.setAppKey(zhizunConfig.getAppKey());
        HttpRequest request = HttpUtil.createPost(zhizunConfig.getUrl() + uri)
                .body(JsonUtils.obj2json(params));
        try (HttpResponse execute = request.execute()) {
            String body = execute.body();
            log.info("【智尊】获取数据结果({})：params={},result={}", buss, params, body);
            ZhizunListResult<T> result = JsonUtils.json2obj(body, ZhizunListResult.class, clazz);
            if (result.success()) {
                return result.data;
            }
            throw new PubException(result.getMsg());
        } catch (PubException e) {
            throw e;
        } catch (Exception e) {
            log.error("【智尊】发起请求失败：params={}", params, e);
            throw new PubException(String.format("【智尊】发起请求失败(%s)", buss));
        }
    }


    private void execute(String uri,
                         ZhizunCommonRequestDTO params,
                         String buss) {
        log.info("【智尊】设置数据({})：params={}", buss, JsonUtils.obj2json(params));
        params.setAppId(zhizunConfig.getAppId());
        params.setAppKey(zhizunConfig.getAppKey());
        HttpRequest request = HttpUtil.createPost(zhizunConfig.getUrl() + uri)
                .body(JsonUtils.obj2json(params));
        try (HttpResponse execute = request.execute()) {
            String body = execute.body();
            ZhizunResult result = JsonUtils.json2obj(body, ZhizunResult.class);
            log.info("【智尊】设置数据结果({})：params={},result={}", buss, params, body);
            if (result.success()) {
                return;
            }
            throw new PubException(result.msg);
        } catch (PubException e) {
            throw e;
        } catch (Exception e) {
            log.error("【智尊】发起请求失败：params={}", params, e);
            throw new PubException(String.format("【智尊】发起请求失败(%s)", buss));
        }
    }

    private String getUid(String imei) {
        try {
            ZhizunWdDeviceLocationQueryResultDTO deviceLocation = this.getDeviceLocation(imei);
            return deviceLocation.getUid();
        } catch (Exception e) {
            throw new PubException(String.format("【智尊】获取imei对应的UID失败:%s", imei));
        }
    }

    @Data
    public static class ZhizunListResult<T> extends ZhizunResult {
        private List<T> data;
    }

    @Data
    public static class ZhizunResult {
        @JsonProperty("Ret")
        private String ret;
        @JsonProperty("Msg")
        private String msg;
        @JsonProperty("msg")
        private String msg2;

        public boolean success() {
            return "Succ".equals(ret)
                    || "success".equals(msg2);
        }
    }
}
